#include "CTimer.h"
CTimer::CTimer()
{
	this->m_CommandStr = "YYYYMMDDHHMISS";
}

CTimer::CTimer(STRING _cmdStr)
{
	this->m_CommandStr = _cmdStr;
}

CTimer::~CTimer()
{
	this->m_CommandStr = "";
}

PSTR CTimer::analy(CTimer::ETimeStrState& _State,PSTR _star)
{
	switch(*_star)
	{
	case 'Y':
		{
			if (*(_star+1) == 'Y' && *(_star+2) == 'Y' && *(_star+3) == 'Y')
			{
				_State = CTimer::YEAR;
				_star += 4;
				return _star;
			}
			break;
		}
	case 'M':
		{
			if (*(_star+1) == 'M')
			{
				_State = CTimer::MONTH;
				_star += 2;
				return _star;
			}
			else if (*(_star+1) == 'I')
			{
				_State = CTimer::MINUTE;
				_star += 2;
				return _star;
			}
			break;
		}
	case 'D':
		{
			if (*(_star+1) == 'D')
			{
				_State = CTimer::DAY;
				_star += 2;
				return _star;
			}
			break;
		}
	case 'H':
		{
			if (*(_star+1) == 'H')
			{
				_State = CTimer::HOUR;
				_star += 2;
				return _star;
			}
			break;
		}
	case 'S':
		{
			if (*(_star+1) == 'S')
			{
				_State = CTimer::SECOND;
				_star += 2;
				return _star;
			}
			break;
		}
	default:
		break;
	}
	do
	{
		if (0 == *_star)
		{
			_State = CTimer::END;
			return _star;
		}
		_star++;
	}
	while(*_star != 'Y' && *_star != 'M' && *_star != 'D' && *_star != 'H' && *_star != 'S');
	_State = CTimer::OTHER;
	return _star;
}

CTimer& CTimer::operator=(const INT& _intValue)
{
	this->m_TimerValue = _intValue;
	return *this;
}

void CTimer::setCommand(STRING _Command)
{
	PSTR _star,_res;
	_star = (PSTR)this ->m_CommandStr.c_str();
	_res = _star;
	this->m_CommandStr = _Command;
}

bool CTimer::input(INT _intValue)
{
	PSTR _star,_res;
	_star = (PSTR)this ->m_CommandStr.c_str();
	_res = _star;
	vector <CTimer::ETimeStrState> tmp_vstate;
	ETimeStrState tmp_state=CTimer::INIT;
	tm tmp_tm;
	memset(&tmp_tm, 0, sizeof(tmp_tm));
	do
	{
		_res = this->analy(tmp_state, _star);
		if (CTimer::END != tmp_state && CTimer::OTHER != tmp_state && CTimer::INIT != tmp_state)
		{
			tmp_vstate.push_back(tmp_state);
		}
		_star = _res;
	}
	while (CTimer::END != tmp_state);
	INT tmp_intValue = _intValue;
	for (vector <CTimer::ETimeStrState>::iterator it = tmp_vstate.end(); it != tmp_vstate.begin();)
	{
		it--;
		switch(*it)
		{
		case CTimer::YEAR:
			{
				tmp_tm.tm_year = (tmp_intValue % 10000) - 1900;
				tmp_intValue /= 10000;
				break;
			}
		case CTimer::MONTH:
			{
				tmp_tm.tm_mon = (tmp_intValue % 100) - 1;
				tmp_intValue /= 100;
				break;
			}
		case CTimer::DAY:
			{
				tmp_tm.tm_mday = tmp_intValue % 100;
				tmp_intValue /= 100;
				break;
			}
		case CTimer::HOUR:
			{
				tmp_tm.tm_hour = tmp_intValue % 100;
				tmp_intValue /= 100;
				break;
			}
		case CTimer::MINUTE:
			{
				tmp_tm.tm_min = tmp_intValue % 100;
				tmp_intValue /= 100;
				break;
			}
		case CTimer::SECOND:
			{
				tmp_tm.tm_sec = tmp_intValue % 100;
				tmp_intValue /= 100;
				break;
			}
		default:
			break;
		}
	}
	this->m_TimerValue = mktime(&tmp_tm);
	if (-1 == this->m_TimerValue)
	{
		return false;
	}
	return true;
}

bool CTimer::input(INT _intValue,STRING _Command)
{
	STRING STR_TMP = this ->m_CommandStr;
	this ->m_CommandStr = _Command;
	bool rt_value =  this->input(_intValue);
	this ->m_CommandStr = STR_TMP;
	return rt_value;
}

bool CTimer::input(STRING _strValue)
{
	PSTR _star,_res,_pstrValue;
	_star = (PSTR)this ->m_CommandStr.c_str();
	_pstrValue = (PSTR)_strValue.c_str();
	_res = _star;
	tm tmp_tm;
	memset(&tmp_tm, 0, sizeof(tmp_tm));
	ETimeStrState tmp_state=CTimer::INIT;
	do
	{
		_res = this->analy(tmp_state, _star);
		switch(tmp_state)
		{
		case CTimer::YEAR:
			{
				PSTR tmp_pstr = new CHAR[5];
				memcpy(tmp_pstr, _pstrValue, 4);
				tmp_pstr[4] = 0;
				stringstream tmp_sstream(tmp_pstr);
				delete[] tmp_pstr;
				tmp_sstream>>tmp_tm.tm_year;
				tmp_tm.tm_year -= 1900;
				_pstrValue += 4;
				break;
			}
		case CTimer::MONTH:
			{
				PSTR tmp_pstr = new CHAR[3];
				memcpy(tmp_pstr, _pstrValue, 2);
				tmp_pstr[2] = 0;
				stringstream tmp_sstream(tmp_pstr);
				delete[] tmp_pstr;
				tmp_sstream>>tmp_tm.tm_mon;
				tmp_tm.tm_mon -= 1;
				_pstrValue += 2;
				break;
			}
		case CTimer::DAY:
			{
				PSTR tmp_pstr = new CHAR[3];
				memcpy(tmp_pstr, _pstrValue, 2);
				tmp_pstr[2] = 0;
				stringstream tmp_sstream(tmp_pstr);
				delete[] tmp_pstr;
				tmp_sstream>>tmp_tm.tm_mday;
				_pstrValue += 2;
				break;
			}
		case CTimer::HOUR:
			{
				PSTR tmp_pstr = new CHAR[3];
				memcpy(tmp_pstr, _pstrValue, 2);
				tmp_pstr[2] = 0;
				stringstream tmp_sstream(tmp_pstr);
				delete[] tmp_pstr;
				tmp_sstream>>tmp_tm.tm_hour;
				_pstrValue += 2;
				break;
			}
		case CTimer::MINUTE:
			{
				PSTR tmp_pstr = new CHAR[3];
				memcpy(tmp_pstr, _pstrValue, 2);
				tmp_pstr[2] = 0;
				stringstream tmp_sstream(tmp_pstr);
				delete[] tmp_pstr;
				tmp_sstream>>tmp_tm.tm_min;
				_pstrValue += 2;
				break;
			}
		case CTimer::SECOND:
			{
				PSTR tmp_pstr = new CHAR[3];
				memcpy(tmp_pstr, _pstrValue, 2);
				tmp_pstr[2] = 0;
				stringstream tmp_sstream(tmp_pstr);
				delete[] tmp_pstr;
				tmp_sstream>>tmp_tm.tm_sec;
				_pstrValue += 2;
				break;
			}
		case CTimer::END:
		case CTimer::OTHER:
			{
				PSTR tmp_pstr = new CHAR [_res - _star + 1];
				PSTR tmp_pstr2 = new CHAR [_res - _star + 1];
				memcpy(tmp_pstr, _pstrValue, _res - _star);
				memcpy(tmp_pstr2, _star, _res - _star);
				tmp_pstr[_res - _star] = 0;
				tmp_pstr2[_res - _star] = 0;
				STRING tmp_str,tmp_str2;
				tmp_str = tmp_pstr;
				tmp_str2 = tmp_pstr2;
				delete[] tmp_pstr;
				delete[] tmp_pstr2;
				if (tmp_str != tmp_str2)
				{
					return false;
				}
				else
				{
					_pstrValue += ( _res - _star);
				}
				break;
			}
		default:
			break;
		}
		_star = _res;
	}
	while (CTimer::END != tmp_state);
	if(0 != *_pstrValue)
	{
		return false;
	}
	this->m_TimerValue = mktime(&tmp_tm);
	if (-1 == this->m_TimerValue)
	{
		return false;
	}
	return true;
}

bool CTimer::input(STRING _strValue,STRING _Command)
{
	STRING STR_TMP = this ->m_CommandStr;
	this ->m_CommandStr = _Command;
	bool rt_value =  this->input(_strValue);
	this ->m_CommandStr = STR_TMP;
	return rt_value;
}


bool CTimer::fromNumber(CValue _CValue)
{
	return this->input(_CValue.getInt());
}


bool CTimer::fromNumber(CValue _CValue, STRING _Command)
{
	return this->input(_CValue.getInt(), _Command);
}

bool CTimer::fromString(CValue _CValue)
{
	return this->input(_CValue.getString());
}

bool CTimer::fromString(CValue _CValue, STRING _Command)
{
	return this->input(_CValue.getString(), _Command);
}



CValue& CTimer::output()
{
	PSTR _star,_res;
	CValue* rt_value = new CValue();
	ETimeStrState tmp_state=CTimer::INIT;
	INT i_res = 0;
	STRING s_res = "";
	_star = (PSTR)this ->m_CommandStr.c_str();
	_res = _star;
	tm* tmp_tm = localtime((time_t*)(&(this->m_TimerValue)));
	if (0 == tmp_tm)
	{
		return *rt_value;
	}
	do
	{
		_res = this->analy(tmp_state, _star);
		switch(tmp_state)
		{
		case CTimer::YEAR:
			{
				i_res *= 10000;
				i_res += tmp_tm->tm_year + 1900;
				stringstream tmp_ss;
				int tmp_int = tmp_tm->tm_year + 1900;
				tmp_ss<<tmp_int;
				s_res += tmp_ss.str();
				break;
			}
		case CTimer::MONTH:
			{
				i_res *= 100;
				i_res += (tmp_tm->tm_mon + 1);
				stringstream tmp_ss;
				int tmp_int = tmp_tm->tm_mon + 1;
				tmp_ss<<tmp_int;
				if(tmp_int < 10)
				{
					s_res += '0';
				}
				s_res += tmp_ss.str();
				break;
			}
		case CTimer::DAY:
			{
				i_res *= 100;
				i_res += tmp_tm->tm_mday;
				stringstream tmp_ss;
				tmp_ss<<tmp_tm->tm_mday;
				if (tmp_tm->tm_mday < 10)
				{
					s_res += '0';
				}
				s_res += tmp_ss.str();
				break;
			}
		case CTimer::HOUR:
			{
				i_res *= 100;
				i_res += tmp_tm->tm_hour;
				stringstream tmp_ss;
				tmp_ss<<tmp_tm->tm_hour;
				if (tmp_tm->tm_hour < 10)
				{
					s_res += '0';
				}
				s_res += tmp_ss.str();
				break;
			}
		case CTimer::MINUTE:
			{
				i_res *= 100;
				i_res += tmp_tm->tm_min;
				stringstream tmp_ss;
				tmp_ss<<tmp_tm->tm_min;
				if (tmp_tm->tm_min < 10)
				{
					s_res += '0';
				}
				s_res += tmp_ss.str();
				break;
			}
		case CTimer::SECOND:
			{
				i_res *= 100;
				i_res += tmp_tm->tm_sec;
				stringstream tmp_ss;
				tmp_ss<<tmp_tm->tm_sec;
				if (tmp_tm->tm_sec < 10)
				{
					s_res += '0';
				}
				s_res += tmp_ss.str();
				break;
			}
		case CTimer::END:
		case CTimer::OTHER:
			{
				PSTR tmp_pstr = new CHAR [_res - _star + 1];
				memcpy(tmp_pstr, _star, _res - _star);
				tmp_pstr[_res - _star] = 0;
				s_res += tmp_pstr;
				delete[] tmp_pstr;
				break;
			}
		default:
			break;
		}
		_star = _res;
	}
	while (CTimer::END != tmp_state);
	if (0 == i_res && "" == s_res)
	{
		i_res = this->m_TimerValue;
		stringstream tmp_ss;
		tmp_ss<<this->m_TimerValue;
		s_res = tmp_ss.str();
	}
	rt_value->setNumber(i_res);
	rt_value->setString(s_res);
	return *rt_value;
	
}

CValue& CTimer::output(STRING _Command)
{
	STRING STR_TMP = this ->m_CommandStr;
	this ->m_CommandStr = _Command;
	CValue& rt_value = this->output();
	this ->m_CommandStr = STR_TMP;
	return rt_value;
}

INT CTimer::getValue()
{
	return this->m_TimerValue;
}



extern "C" _DLLFUNC PCTimer CreateNewCTimerNULL()
{
	return new CTimer(); 
}

extern "C" _DLLFUNC PCTimer CreateNewCTimerStr(STRING _cmdStr)
{
	return new CTimer(_cmdStr);
}
extern "C" _DLLFUNC void Test()
{
	STRING a = "";
	a += "fuck";
	cout<<a<<endl;
}

